package com.ctrun.view.cateye.indicatorview.widget;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;

import androidx.annotation.Nullable;
import androidx.core.content.ContextCompat;
import androidx.recyclerview.widget.RecyclerView;
import androidx.viewpager2.widget.ViewPager2;

import com.ctrun.view.cateye.indicatorview.R;
import com.ctrun.view.cateye.indicatorview.widget.banner.LoopAdapter;

/**
 * @author ctrun on 2022/7/25.
 * 轮播图指示器
 */
public class IndicatorView extends View {
    private static final String TAG = "IndicatorView";

    public IndicatorView(Context context) {
        this(context, null);
    }

    public IndicatorView(Context context, @Nullable AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public IndicatorView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init(context, attrs);
    }

    private int mItemCount;
    private int mDefaultWidth;
    private int mDefaultHeight;
    private final Paint mBackgroundPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
    private final Paint mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
    private void init(Context context, AttributeSet attrs) {
        TypedArray a = context.getTheme().obtainStyledAttributes(attrs, R.styleable.IndicatorView, 0, 0);
        try {
            int backgroundColor = a.getColor(R.styleable.IndicatorView_indicator_background_color, Color.parseColor("#60ffffff"));
            int mSelectedColor = a.getColor(R.styleable.IndicatorView_selected_indicator_color, ContextCompat.getColor(context, R.color.white));

            mBackgroundPaint.setColor(backgroundColor);
            mPaint.setColor(mSelectedColor);
        } finally {
            a.recycle();
        }

        mDefaultWidth = dipsToPixels(100);
        mDefaultHeight = dipsToPixels(3);
    }

    private void setItemCount(int itemCount) {
        mItemCount = itemCount;
        mDefaultWidth = (mItemCount <= 4 ? dipsToPixels(40) : dipsToPixels(100));

        if (mItemCount <= 1) {
            setVisibility(GONE);
        } else {
            setVisibility(VISIBLE);
        }

        requestLayout();
    }

    private final ViewPager2DataObserver mDataObserver = new ViewPager2DataObserver();
    private ViewPager2 mViewPager2;
    @SuppressWarnings("rawtypes")
    private LoopAdapter mLoopAdapter;
    public void attachToViewPager2(ViewPager2 viewPager2) {
        if (mViewPager2 == viewPager2) {
            return;
        }

        if (mViewPager2 != null) {
            mViewPager2.unregisterOnPageChangeCallback(mOnPageChangeCallback);
        }

        if (mLoopAdapter != null) {
            mLoopAdapter.unregisterAdapterDataObserver(mDataObserver);
        }

        mViewPager2 = viewPager2;
        if (mViewPager2 != null) {
            //noinspection rawtypes
            mLoopAdapter = (LoopAdapter) mViewPager2.getAdapter();
            if (mLoopAdapter != null) {
                mLoopAdapter.registerAdapterDataObserver(mDataObserver);
                setItemCount(mLoopAdapter.getRealItemCount());
            } else {
                setItemCount(0);
            }

            mViewPager2.registerOnPageChangeCallback(mOnPageChangeCallback);
        }
    }

    private final ViewPager2.OnPageChangeCallback mOnPageChangeCallback = new ViewPager2.OnPageChangeCallback() {
        @Override
        public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
            if (mLoopAdapter != null) {
                int realPosition = mLoopAdapter.getRealPosition(position);
                setProgress(realPosition, positionOffset);
            }
        }

        @Override
        public void onPageSelected(int position) {
            if (mLoopAdapter != null) {
                int realPosition = mLoopAdapter.getRealPosition(position);
                setProgress(realPosition, 0.f);
            }
        }

    };

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        int width = resolveSize(mDefaultWidth, widthMeasureSpec);
        int height = resolveSize(mDefaultHeight, heightMeasureSpec);
        setMeasuredDimension(width, height);
    }

    private int mPosition;
    private float mProgress;
    public void setProgress(int position, float progress) {
        mPosition = position;
        mProgress = Math.abs(progress);
        invalidate();
    }

    @Override
    protected void onDraw(Canvas canvas) {
        Log.d(TAG, "position: " + mPosition + ",progress: " + mProgress);

        if (mItemCount == 0) {
            return;
        }

        final int width = getWidth();
        final int height = getHeight();

        final float itemWidth = (float) width / mItemCount;

        //绘制背景
        canvas.drawRect(0, 0, width, height, mBackgroundPaint);

        canvas.drawRect(mPosition * itemWidth + mProgress * itemWidth, 0, (mPosition + 1) * itemWidth + itemWidth * mProgress, height, mPaint);
        if (mPosition == mItemCount - 1) {
            canvas.drawRect(0, 0, itemWidth * mProgress, height, mPaint);
        }
    }

    private int dipsToPixels(int dips) {
        float scale = getContext().getResources().getDisplayMetrics().density;
        return (int) (dips * scale + 0.5f);
    }



    private class ViewPager2DataObserver extends RecyclerView.AdapterDataObserver {
        ViewPager2DataObserver() {}

        @Override
        public void onChanged() {
            setItemCount(mLoopAdapter == null ? 0 : mLoopAdapter.getRealItemCount());
        }

        @Override
        public void onItemRangeChanged(int positionStart, int itemCount) {
            onChanged();
        }

        @Override
        public void onItemRangeChanged(int positionStart, int itemCount, @Nullable Object payload) {
            onChanged();
        }

        @Override
        public void onItemRangeInserted(int positionStart, int itemCount) {
            onChanged();
        }

        @Override
        public void onItemRangeRemoved(int positionStart, int itemCount) {
            onChanged();
        }

        @Override
        public void onItemRangeMoved(int fromPosition, int toPosition, int itemCount) {
            onChanged();
        }
    }
}
